valorAbsoluto :: Float -> Float
valorAbsoluto x = if x >= 0 then x else -x

factorial :: Integer -> Integer
factorial	0 = 1
factorial	1 = 1
factorial	n = n * factorial (n-1)


cantDivisoresPrimos :: Integer -> Int
cantDivisoresPrimos n = length [ x | x <- [2..n], n `mod` x == 0, esPrimo x]

esPrimo :: Integer -> Bool
esPrimo 1 = False
esPrimo 2 = True
esPrimo n = esPrimoAux n (n-1)

esPrimoAux :: Integer -> Integer -> Bool
esPrimoAux n 2 = n `mod` 2 /= 0
esPrimoAux n div = n `mod` div /= 0 && esPrimoAux n (div-1)


inverso :: Float -> Maybe Float
inverso 0 = Nothing
inverso x = Just (1 / x)


aEntero :: Either Int Bool -> Int
aEntero (Left x) = x
aEntero (Right b) = if b then 1 else 0


limpiar :: String -> String -> String
limpiar [] y = y
limpiar (x:xs) y = limpiar xs (limpiarCaracter x y)

limpiarCaracter :: Char -> String -> String
limpiarCaracter c [] = []
limpiarCaracter c (x:xs) = if c == x then (limpiarCaracter c xs) else (x:limpiarCaracter c xs)


difPromedio :: [Float] -> [Float]
difPromedio s = map (\x -> x - (promedio s)) s

promedio :: [Float] -> Float
promedio s = foldr (\x res -> res + (x / (fromIntegral (length s)))) 0 s


todosIguales :: [Integer] -> Bool
todosIguales [] = True
todosIguales [x] = True
todosIguales (x:y:xs) = x == y && todosIguales (y:xs)


data AB a = Nil | Bin (AB a) a (AB a) deriving Show

nullTree :: AB a -> Bool
nullTree Nil = True
nullTree (Bin _ _ _) = False


mapAB :: (a -> b) -> AB a -> AB b
mapAB _ Nil = Nil
mapAB f (Bin l n r) = Bin (mapAB f l) (f n) (mapAB f r)

negTree :: AB Bool -> AB Bool
negTree = mapAB not

{-
data Lista a = [] | (a:(Lista a))
foldr :: (a -> b -> b) -> b -> Lista a -> b
foldr _ base [] = base
foldr f base (x:xs) = f x (foldr f base xs)
-}

prodTree :: AB Integer -> Integer
prodTree = foldAB (\n resL resR -> n * resL * resR) 1

foldAB :: (a -> b -> b -> b) -> b -> AB a -> b
foldAB _ base Nil = base
foldAB f base (Bin l n r) = f n (foldAB f base l) (foldAB f base r)
